{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a8bad68e",
   "metadata": {},
   "source": [
    "### 第一题"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5dd42310",
   "metadata": {},
   "source": [
    "1、通过模型得到测试集10个样本的标签（编程题）\n",
    "\n",
    "4个正样本的概率分别是：0.6 0.8 0.2 0.9\n",
    "\n",
    "6个负样本的概率分别是：0.1 0.2 0.2 0.3 0.6 0.7\n",
    "\n",
    "请用代码实现计算出AUC的值（PS：概率值相等按0.5计算）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "5fbb2d78",
   "metadata": {},
   "outputs": [],
   "source": [
    "def calAUC(prob,labels):\n",
    "    f = list(zip(prob,labels))\n",
    "    rank = [values2 for values1,values2 in sorted(f,key=lambda x:x[0])]\n",
    "    print(rank)\n",
    "    rankList = [i+1 for i in range(len(rank)) if rank[i]==1]\n",
    "    print(rankList)\n",
    "    posNum = 0\n",
    "    negNum = 0\n",
    "    for i in range(len(labels)):\n",
    "        if(labels[i]==1):\n",
    "            posNum+=1\n",
    "        else:\n",
    "            negNum+=1\n",
    "    auc = 0\n",
    "    auc = float(sum(rankList)- (posNum*(posNum+1))/2)/(posNum*negNum)\n",
    "    return auc\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "efd40f91",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10\n",
      "10\n",
      "[-1, 1, -1, -1, -1, 1, -1, -1, 1, 1]\n",
      "[2, 6, 9, 10]\n",
      "0.7083333333333334\n"
     ]
    }
   ],
   "source": [
    "# 4个正样本的概率分别是：0.6 0.8 0.2 0.9\n",
    "\n",
    "# 6个负样本的概率分别是：0.1 0.2 0.2 0.3 0.6 0.7\n",
    "\n",
    "pred =[0.6, 0.8, 0.2, 0.9, 0.1, 0.2, 0.2, 0.3, 0.6, 0.7]\n",
    "y=[1,1,1,1,-1,-1,-1,-1,-1,-1]\n",
    "print(len(y))\n",
    "print(len(pred))\n",
    "print(calAUC(pred,y))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a7c517c",
   "metadata": {},
   "source": [
    "### 第二题"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07aa767f",
   "metadata": {},
   "source": [
    "2、（问答题）小韩和小李是一家互联网公司的实习生，他们刚入职就接受了一项任务，用机器学习的方法来预测某个行业query和广告之间的点击率。该模型将会用于对广告展现时，根据点击率，对展现的广告做重排序。他们两个都采用了LR方法来解决问题，具体的做法是：\n",
    "\n",
    "（1）根据一个月该行业的日志，找到每次搜索时，当时展现的所有广告（一次展现固定出三条广告）。他们把每个广告的每次展现当作样本，当时是否点击为LR的y值：0或者1。这样一共获得了50w个样本（比如在一次搜索queryA下展现了三条广告a，b，c，其实a被点击了一次，那么这次搜索一共对应3个样本，其中第一个样本的y为1，后面两个样本的y为0）\n",
    "\n",
    "（2）对样本做均匀抽样分成两份，70%为训练样本，30%为测试样本，抽取了100种特征，其中一个特征是当时广告在网页中的排序（1，2或者3）\n",
    "\n",
    "（3）使用公司的LR在训练样本上进行训练，在测试样本中进行检测， 认为LR模型给出的p即为广告的点击率，其中  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "72d3311c",
   "metadata": {},
   "source": [
    "a.对于广告在网页中的排序，小韩使用的方法是离散乘0-1特征，即将排序离散成（是否为第一名，是否为第二名，是否为第三名），如果样本的排序是第一名，对应的特征为（1,0,0），如果样本的排序为第二名，对应的特征为（0,1,0），而小李的方法是直接对排序做归一后当作特征的取值，如第一名为0，第二名为0.5，第三名为1，问他们谁的方法效果会更好，为什么？  \n",
    "\n",
    "**答：**我认为小李的方法会更好。one-hot编码适合用于每个状态都完全独立的情况，需要one-hot encoding 是因为一些离散的值是没有比较大小的意义，比如gender=[“man”,”female”]，city = [“shanghai”,”hefei”,”wuhan”]，而广告在网页中的排序，有数值大小，理论上广告在网页中排序靠前，更能使用户点击该广告。\n",
    "\n",
    "b.一般大型LR模型都是使用随机梯度下降的方式，所以需要选择初始值，小韩把beta()的初始值设置成了广告的平均点击0.01，而小李把bata()设置为1，问在实际线上应用的时候，他们谁的方法效果会更好，为什么？  \n",
    "\n",
    "**答：**beta()初始值设定没有固定原则，beta()的几何意义是截距，就是在特征权值w全为0的情况下的取值，从另外一个角度看，就是对一个全新的商品赋予的点击率。通常可以取平均值，取1的话就是赋予一个全新商品100%的点击率， 有点过高，不太可取\n",
    "\n",
    "c.在直接使用LR模型的时候(loss=\\sum yi*log(h(x))+(1-yi)*log(1-h(x)))h(x）=1/(1+exp(-xi*thetai)),小韩和小李发现在训练样本中拟合的很好，但是在测试样本中效果比较差，问可能是什么原因导致？怎么解决？  \n",
    "\n",
    "**答：**从loss可以看出，他们采用的是经验风险最小化，当训练集合很小而训练集合的元素特征又比较多的时候，单单使用经验风险最小化函数，会造成模型过拟合现象。而结构风险最小化是为了防止过拟合而提出的策略。结构风险最小化等价于正则化。结构风险在经验风险的基础上加上表示模型复杂度的正则化项，降低模型复杂度，提升模型的可预测性。它的做法就是在经验最小化的基础上增加一个正则化因子，正则化项可以是参数向量的L1范数，也可以是L2范数！业界通常采用LR+L1的做法（Lasso回归）。为什么选择L1而不是L2，主要是L1是一种稀疏型学习方法。\n",
    "\n",
    "d.在测试的时候，他们使用auc来评估效果，请问auc是怎么计算的？\n",
    "\n",
    "答：AUC值为ROC曲线所覆盖的区域面积，显然，AUC越大，分类器分类效果越好。\n",
    "\n",
    "ROC是横坐标为False Positive Rate（FPR），纵坐标是True Positive Rate（TPR）的二维平面上的曲线。\n",
    "\n",
    "TPR就是我们常谈到的召回率。\n",
    "\n",
    "​    AUC计算公式：\n",
    "\n",
    "![](C:\\Users\\zlx\\AppData\\Roaming\\Typora\\typora-user-images\\image-20210818163337306.png)\n",
    "\n",
    "\n",
    "\n",
    "具体实现见第一题编程\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6411a655",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
